package main

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"os"
	"strings"
	"time"
)

var mux map[string]func(http.ResponseWriter, *http.Request)

type myHandler struct{}

// var complete chan int = make(chan int)

func (*myHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	url := r.URL.String()
	//url带有参数时的处理
	//strings.IndexByte(url, '?')//查找第一次出现位置，未找到返回-1
	if strings.Contains(url, "?") { //含有？
		idx := strings.Index(url, "?") // ? 所在位置
		rs := []rune(url)
		url = string(rs[0:idx])
		fmt.Printf("url is %s\n", url)
	}

	if h, ok := mux[url]; ok {
		//处理跨域请求的头
		w.Header().Set("Access-Control-Allow-Origin", r.Header.Get("Origin"))
		w.Header().Set("Access-Control-Allow-Credentials", "true")
		w.Header().Add("Access-Control-Allow-Method", "POST, OPTIONS, GET, HEAD, PUT, PATCH, DELETE")
		w.Header().Add("Access-Control-Allow-Headers", "Origin,X-Requested-With,X-HTTP-Method-Override,accept-charset,accept-encoding,Content-Type,Accept,Cookie,x-token")
		w.Header().Set("Content-Type", "application/json; charset=utf-8")

		if r.Method == "OPTIONS" {
			w.Header().Set("Content-Type", " application/x-www-form-urlencoded")
			// //设置状态码
			// w.WriteHeader(200)
			// io.WriteString(w, "")
			return
		}

		h(w, r)
		return
	}

	io.WriteString(w, "URL:"+r.URL.String())
}

func main() {
	server := http.Server{
		Addr:        ":8080",
		Handler:     &myHandler{},
		ReadTimeout: 5 * time.Second,
	}

	mux = make(map[string]func(http.ResponseWriter, *http.Request))

	mux["/hello"] = sayHello
	mux["/bye"] = sayBye
	mux["/login"] = login
	mux["/user/login"] = userLogin
	mux["/user/info"] = userInfo
	mux["/echo"] = echo

	log.Println("server start ...")

	err := server.ListenAndServe()
	if err != nil {
		log.Fatal(err)
	}

}

type Response struct {
	Code int
	Msg  string
	Data interface{}
}

//有跨域请求的
/*func CorsHeader(inner http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Access-Control-Allow-Origin", r.Header.Get("Origin"))
		w.Header().Set("Access-Control-Allow-Credentials", "true")
		w.Header().Add("Access-Control-Allow-Method", "POST, OPTIONS, GET, HEAD, PUT, PATCH, DELETE")
		w.Header().Add("Access-Control-Allow-Headers", "Origin,X-Requested-With,X-HTTP-Method-Override,accept-charset,accept-encoding,Content-Type,Accept,Cookie,x-token")
		w.Header().Set("Content-Type", "application/json")
		inner.ServeHTTP(w, r)
		//设置响应头
		// w.Header().Set("Connection", "keep-alive")
		// w.Header().Set("Access-Control-Allow-Origin", "http://localhost:9528")
		// w.Header().Set("Access-Control-Allow-Methods", "GET,HEAD,PUT,POST,DELETE,PATCH")
		// w.Header().Add("Access-Control-Allow-Headers", "Content-Type") //header的类型
		// w.Header().Set("Access-Control-Allow-Credentials", "true")
		// w.Header().Set("Access-Control-Max-Age", "2592000")
		// w.Header().Set("Vary", "Accept, Origin")
		// w.Header().Set("Server", "goServer")
	})
}*/

func sayHello(w http.ResponseWriter, r *http.Request) {
	io.WriteString(w, "Hello World, this is version 3")
	// complete <- 0
}

func sayBye(w http.ResponseWriter, r *http.Request) {
	io.WriteString(w, "Bye Bye, this is version 3")
}

func userLogin(w http.ResponseWriter, r *http.Request) {

	ret := `{"code": 20000,"data": { "token": "admin"}}`
	//设置响应头
	// w.Header().Set("Content-Type", "application/json; charset=utf-8")

	io.WriteString(w, ret)

}

func userInfo(w http.ResponseWriter, r *http.Request) {

	ret := "{\"code\":20000,\"data\":{\"role\":[\"admin\"],\"name\":\"admin\",\"avatar\":\"\"}}"
	//设置响应头
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	log.Printf("userInfo %s\n", r.Method)
	io.WriteString(w, ret)

}

//输出请求信息
func echo(w http.ResponseWriter, r *http.Request) {
	echoRequestInfo(r)
	var response = Response{
		Code: 200,
		Msg:  "success",
		Data: nil,
	}
	str, _ := json.Marshal(response)
	io.WriteString(w, string(str))
}

func login(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	var uName string
	var pwd string

	//请求类型
	method := r.Method
	fmt.Printf("Request Method = %s \n", method)

	switch method {
	case "GET":
		//取get请求参数
		if len(r.Form["uName"]) > 0 {
			uName = r.Form["uName"][0]
		}
		if len(r.Form["pwd"]) > 0 {
			pwd = r.Form["pwd"][0]
		}
	case "POST":
		//既可以取post请求参数，又可以取get请求参数，以post为先
		reqForm, err := url.ParseQuery(r.URL.RawQuery)
		checkErr(err)
		if len(reqForm["uName"]) > 0 {
			uName = reqForm["uName"][0]
		}
		if len(reqForm["pwd"]) > 0 {
			pwd = reqForm["pwd"][0]
		}
	default:
		fmt.Println("未知请求")

	}

	//POST 请求
	/*if "POST" == method {
		//获取post参数
		uName = r.PostFormValue("uName")
		pwd = r.PostFormValue("pwd")
	}*/

	//有文件上传时
	/*r.ParseMultipartForm(32 << 20)
	if r.MultipartForm != nil {
		values := r.MultipartForm.Value["id"]
		if len(values) > 0 {
			fmt.Fprintln(w, values[0])
		}
	}*/

	//获取Cookie参数
	/*cookie, err := r.Cookie("uName")
	if err == nil {
		fmt.Fprintln(w, "Domain:", cookie.Domain)
		fmt.Fprintln(w, "Expires:", cookie.Expires)
		fmt.Fprintln(w, "Name:", cookie.Name)
		fmt.Fprintln(w, "Value:", cookie.Value)
	}*/

	fmt.Printf("UserName is %s, Password is %s \n", uName, pwd)

	io.WriteString(w, uName+" login success!")
}

func checkErr(err error) {
	if err != nil {
		fmt.Fprintf(os.Stderr, "Fatal error:%s", err.Error())
		// os.Exit(1)
	}
}

func echoRequestInfo(r *http.Request) {
	method := r.Method
	log.Printf("----------Method : %s", method)

	host := r.Host
	log.Printf("------------Host : %s", host)

	agent := r.UserAgent()
	log.Printf("-----------Anget : %s", agent)

	hander := r.Header
	log.Println("----------Header----------")
	for k, v := range hander {
		log.Printf("%s:%s\n", k, v[0])
	}

	reqForm, _ := url.ParseQuery(r.URL.RawQuery)
	for k, v := range reqForm {
		log.Printf("-----------Param : %s:%s", k, v[0])
	}

	body, _ := ioutil.ReadAll(r.Body)
	log.Printf("------------Body : %s", body)

	// reqForm, _ := url.ParseQuery(r.URL.RawQuery)
	// log.Println(reqForm.Encode())
	log.Println("----------Echo end----------")
}

//
//                       _oo0oo_
//                      o8888888o
//                      88" . "88
//                      (| -_- |)
//                      0\  =  /0
//                    ___/`---'\___
//                  .' \\|     |// '.
//                 / \\|||  :  |||// \
//                / _||||| -:- |||||- \
//               |   | \\\  -  /// |   |
//               | \_|  ''\---/''  |_/ |
//               \  .-\__  '-'  ___/-. /
//             ___'. .'  /--.--\  `. .'___
//          ."" '<  `.___\_<|>_/___.' >' "".
//         | | :  `- \`.;`\ _ /`;.`/ - ` : | |
//         \  \ `_.   \_ __\ /__ _/   .-` /  /
//     =====`-.____`.___ \_____/___.-`___.-'=====
//                       `=---='
//
//
//     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//               佛祖保佑         永无BUG
//
